package de.tum.in.eist.poll.shared;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

/**
 * Lecture class represents a single lecture of a certain subject.
 * 
 * @author andriy.stefanov@gmail.com
 * 
 */
@PersistenceCapable
public class Lecture implements Serializable {

	@NotPersistent
	private static final long serialVersionUID = 1L;
	
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
    private String key;

	/**
	 * topic of this single lecture
	 */
	@Persistent
	private String topic = "";

	/**
	 * lecturer who has created this lecture
	 */
	@NotPersistent
	private User lecturer;
	
	@Persistent
	private String lecturerKey;

	/**
	 * publishing date of this lecture
	 */
	@Persistent
	private Date date;

	/**
	 * List of all feedbacks this lesson has received
	 */
	@NotPersistent
	private ArrayList<Feedback> feedbacks = new ArrayList<Feedback>();

	/**
	 * Create new lecture. This constructor is needed by serialization. Please
	 * do not use this default constructor to create new instances. The lecture
	 * created by this constructor has no topic, a dummy lecturer user and no
	 * feedbacks.
	 */
	public Lecture() {
		this("", new User(), new Date(), new ArrayList<Feedback>());
	}

	/**
	 * Create new lecture. The lecture created by this constructor has no
	 * initial feedbacks.
	 * 
	 * @param topic
	 *            - Topic of this lecture (e.g. "Introduction")
	 * @param lecturer
	 *            - lecturer who has created this lecture and will hold it as
	 *            well
	 */
	public Lecture(String topic, User lecturer, Date date) {
		this(topic, lecturer, date, new ArrayList<Feedback>());
	}

	/**
	 * Create new lecture.
	 * 
	 * @param topic
	 *            - Topic of this lecture (e.g. "Introduction")
	 * @param lecturer
	 *            - lecturer who has created this lecture and will hold it as
	 *            well
	 * @param feedbacks
	 *            - initial feedbacks list
	 */
	public Lecture(String topic, User lecturer, Date date,
			ArrayList<Feedback> feedbacks) {
		this.topic = topic;
		this.lecturer = lecturer;
		this.lecturerKey = lecturer.getKey();
		this.date = date;
		this.feedbacks = feedbacks;
	}

	/**
	 * the topic of this lecture
	 * 
	 * @return the topic
	 */
	public String getTopic() {
		return topic;
	}

	/**
	 * the lecturer of this lecture
	 * 
	 * @return the lecturer
	 */
	public User getLecturer() {
		return lecturer;
	}

	/**
	 * list of feedbacks of this lecture
	 * 
	 * @return the feedbacks
	 */
	public ArrayList<Feedback> getFeedbacks() {
		return feedbacks;
	}

	/**
	 * add a {@link Feedback} to the feedback list
	 * 
	 * @param feedback
	 *            - the new feedback
	 */
	public void addFeedback(Feedback feedback) {
		feedback.setLectureKey(this.key);
		feedbacks.add(feedback);
	}
	
	public void setFeedbacks(ArrayList<Feedback> feedbacks){
		this.feedbacks = feedbacks;
	}

	/**
	 * Remove all informations from this object, which are not supposed to be
	 * send to the current user. this means: remove all user informations from
	 * the feedbacks if the current user is a lecturer. if current user is a
	 * student, remove all feedbacks from this lecture except for his own one.
	 * 
	 * @param user - user, this lecture is send to
	 */
	public void anonymize(User user) {
		if (user.isLecturer()) {
			for (Feedback f : feedbacks) {
				f.anonymize();
			}
		} else if (user.isStudent()) {
			for(Feedback f : feedbacks){
				if(!f.getAuthor().equals(user))
					f.removeAnswers();
			}
		}
	}

	/**
	 * summarize all answers to an array. needed to draw chart diagrams.
	 * 
	 * @return integer array with sums of all answers
	 */
	public int[] getStats() {
		int[] result = new int[5];
		for (Feedback f : feedbacks)
			result[f.getAnswer()]++;
		return result;
	}

	/**
	 * check if the current user has already submitted his feedback about this
	 * lecture.
	 * 
	 * @param user
	 * @return {@code true} if this student already has answered, {@code false}
	 *         if not or if the user is a lecturer.
	 */
	public boolean userHasRatedLecture(String userKey) {
//		System.out.println("hasRated: " + userKey);
			for (Feedback f : feedbacks)
				if (f.getAuthorKey().equals(userKey))
					return true;
		return false;
	}

	/**
	 * @return the date
	 */
	public Date getDate() {
		return date;
	}
	
	@Override
	public boolean equals(Object o){
		if(o instanceof Lecture){
			return ((Lecture)o).key.equals(this.key);
		}
		return false;
	}
		
	/**
	 * This method puts the date parameter of lecture into a readable format DD. MM. YYYY
	 * @return the date DD. MM. YYYY
	 */
	public String getStringDate(){
		String str = "";
		if ((date.getDate()) < 10) {
			str += "0" + (date.getDate());
		} else {
			str += (date.getDate());
		}
		str += ". ";
		if (date.getMonth() + 1 < 10) {
			str += "0" + (date.getMonth() + 1);
		} else {
			str += date.getMonth();
		}
		str += ". " + (date.getYear() + 1900);		
		return str;
	}

	/**
	 * @param date the date to set
	 */
	public void setDate(Date date) {
		this.date = date;
	}

	public String toString(){
		String str = "Topic: " + topic + " Lecturer: " + lecturer.getEmail() + " Date: " + this.getStringDate();
		for(Feedback f : feedbacks){
			str += " " + f.getAnswer() + "|" + f.getPositiveAnswer()+"|" + f.getNegativeAnswer();
		}
		return str;
	}
	
	public String getKey(){
		return key;
	}

	public String getLecturerKey() {
		return lecturerKey;
	}

	public void setLecturer(User lecturer) {
		this.lecturerKey = lecturer.getKey();
		this.lecturer = lecturer;
	}
}